/**
 *  发现，大多数的页面都是 表格，表格都会做 1.分页 2.搜索 3.一开始就会显示数据
 *    分析发现，这套流程中，只有两个东西在变： 1. 请求的接口函数 2.搜索的条件 -- 把这两个东西作为函数的参数
 *    分析发现：需要对外暴露的数据
 *      1. 数组  2.数据总数  3.分页的当前面和页容量 4. 请求数据的函数
 * 
 */

import axios from "axios";
import { reactive, ref, toRefs, watch } from "vue";

export function useTable<T>(fatchApi: (...rest: any) => RSP<IResult<T>>, searchParams: Object) {
  const list = ref<T[]>([])
  // 数据总条数
  const count = ref(0)
  // 请求参数是和页面上的 表单相关联的所以需要在外面声明进行后续绑定
  const params = reactive<IUserListParams>({
    keyword: '',
    pageNum: 1,
    pageSize: 10
  })
  // 合并所有需要进行搜索的参数
  Object.assign(params, searchParams)

  // 定义取消请求相关的变量
  let getting = false; // 是否正在请求中
  let source: any;
  function getData() {
    getting = true;
    source = axios.CancelToken.source();
    fatchApi(params, source.token).then(res => {
      if (res.code === 200) {
        // @ts-ignore
        list.value = res.data.list;
        count.value = res.data.total;
      }
    }).finally(() => {
      getting = false
    })
  }
  getData();

  // 当 pageNum 和 pageSize 发生变化时，重新请求数据
  watch([() => params.pageNum, () => params.pageSize], (newVals, oldVals) => {
    // 如果变化的是 pageSize , 需要把pageNum 重置为1，保证一定有数据出现
    let [, newPage] = newVals;
    let [, oldPage] = oldVals;
    if (newPage !== oldPage) {
      params.pageNum = 1
    }
    // 我们发现，如果当pageNum比较大，切换了pageSize，可能会导致数据不够了，我们我解决方案是当pageSize变化时，pageNum重置为1。但是这样做导致两个数据都变了，发送了两次请求
    // 解决方案： 当发送第二次请求的时候，判断第一次是否还在请求中，如果还在请求中，则取消上一次请求
    // 如何取消

    // 如果正在请求中
    if (getting) {
      // 取消上一次请求
      source.cancel();
    }
    getData()
  })

  const { pageNum, pageSize } = toRefs(params);
  return {
    list,
    count,
    getData,
    pageNum,
    pageSize
  }
}